﻿//using System;
//using System.Security.Cryptography;
//using Furion.DependencyInjection;
//using Furion.DistributedIDGenerator;
//using Microsoft.Extensions.Options;
//using Project5.Core.Options;

//namespace Project5.Core.Provides
//{
//    /* This code is taken from jhtodd/SequentialGuid https://github.com/jhtodd/SequentialGuid/blob/master/SequentialGuid/Classes/SequentialGuid.cs */

//    [Injection(Order = 1)]
//    public class SequentialGuidGenerator : IDistributedIDGenerator, ISingleton
//    {
//        private const byte Version = 4;
//        private const byte Variant = 8;
//        private const byte FilterHighBit = 0b00001111;
//        private const byte FilterLowBit = 0b11110000;
//        private static readonly RandomNumberGenerator RandomNumberGenerator = RandomNumberGenerator.Create();
//        private SequentialGuidGeneratorOptions Options { get; }

//        public SequentialGuidGenerator(IOptions<SequentialGuidGeneratorOptions> options)
//        {
//            Options = options.Value;
//        }

//        public object Create(object idGeneratorOptions = null)
//        {
//            var options = (idGeneratorOptions as SequentialGuidGeneratorOptions) ?? Options;

//            return Create(options.GetDefaultSequentialGuidType());
//        }

//        private Guid Create(SequentialGuidType guidType)
//        {
//            // see: What is a GUID? http://guid.one/guid
//            // see: https://github.com/richardtallent/RT.Comb#gory-details-about-uuids-and-guids
//            // According to RFC 4122:
//            // dddddddd-dddd-Mddd-Ndrr-rrrrrrrrrrrr
//            // - M = RFC 版本（version）, 版本4的话，值为4
//            // - N = RFC 变体（variant），值为 8, 9, A, B 其中一个，这里固定为8
//            // - d = 从公元1年1月1日0时至今的时钟周期数（DateTime.UtcNow.Ticks）
//            // - r = 随机数（random bytes）

//            var randomBytes = new byte[8];
//            RandomNumberGenerator.GetBytes(randomBytes);

//            var timestamp = DateTime.UtcNow.Ticks;

//            var timestampBytes = BitConverter.GetBytes(timestamp);
//            if (BitConverter.IsLittleEndian)
//            {
//                Array.Reverse(timestampBytes);
//            }

//            var guidBytes = new byte[16];

//            // /// <summary>
//            // /// 用于 MySql 和 PostgreSql.当使用 Guid.ToString() 方法进行格式化时连续.
//            // /// </summary>
//            // SequentialAsString,
//            //
//            // /// <summary>
//            // /// 用于 Oracle.当使用 Guid.ToByteArray() 方法进行格式化时连续.
//            // /// </summary>
//            // SequentialAsBinary,
//            //
//            // /// <summary>
//            // /// 用以 SqlServer.连续性体现于 GUID 的第4块（Data4）.
//            // /// </summary>
//            // SequentialAtEnd
            
//            switch (guidType)
//            {
//                case SequentialGuidType.SequentialAsString:
//                case SequentialGuidType.SequentialAsBinary:

//                    // AsString: dddddddd-dddd-Mddd-Ndrr-rrrrrrrrrrrr
//                    Buffer.BlockCopy(timestampBytes, 0, guidBytes, 0, 6); // 时间戳前6个字节，共48位
//                    guidBytes[6] =
//                        (byte)((Version << 4) |
//                               ((timestampBytes[6] & FilterLowBit) >> 4)); // 高4位为版本 | 低4位取时间戳序号[6]的元素的高4位
//                    guidBytes[7] = (byte)(((timestampBytes[6] & FilterHighBit) << 4) |
//                                          ((timestampBytes[7] & FilterLowBit) >> 4)); // 高4位取：[6]低4位 | 低4位取：[7]高4位
//                    guidBytes[8] =
//                        (byte)((Variant << 4) | (timestampBytes[7] & FilterHighBit)); // 高4位为：变体 | 低4位取：[7]低4位
//                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 9, 7); // 余下7个字节由随机数组填充

//                    // .NET中，Data1、Data2、Data3 块 分别视为 Int32、Int16、Int16，在小端系统，需要翻转这3个块。
//                    if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
//                    {
//                        Array.Reverse(guidBytes, 0, 4);
//                        Array.Reverse(guidBytes, 4, 2);
//                        Array.Reverse(guidBytes, 6, 2);
//                    }

//                    break;

//                case SequentialGuidType.SequentialAtEnd:

//                    // AtEnd: rrrrrrrr-rrrr-Mxdr-Nddd-dddddddddddd
//                    // Block: 1        2    3    4    5
//                    // Data4 = Block4 + Block5
//                    // 排序顺序：Block5 > Block4 > Block3 > Block2 > Block1
//                    // Data3 = Block3 被认为是 uint16，排序并不是从左到右，为消除影响，x 位取固定值

//                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 6);
//                    guidBytes[6] = (byte)(Version << 4); // Mx 高4位为版本 | 低4位取：全0
//                    guidBytes[7] =
//                        (byte)(((timestampBytes[7] & FilterHighBit) << 4) | (randomBytes[7] & FilterHighBit));
//                    ; // dr 高4位为：时间戳[7]低4位 | 低4位取：随机数
//                    guidBytes[8] =
//                        (byte)((Variant << 4) |
//                               ((timestampBytes[6] & FilterLowBit) >> 4)); // Nd 高4位为：变体 | 低4位取：时间戳[6]高4位
//                    guidBytes[9] = (byte)(((timestampBytes[6] & FilterHighBit) << 4) |
//                                          ((timestampBytes[7] & FilterLowBit) >>
//                                           4)); // dd 高4位为：时间戳[6]低4位 | 低4位取：时间戳[7]高4位
//                    Buffer.BlockCopy(timestampBytes, 0, guidBytes, 10, 6); // 时间戳前6个字节

//                    if (BitConverter.IsLittleEndian)
//                    {
//                        Array.Reverse(guidBytes, 6, 2); // 包含版本号的 Data3 块需要翻转
//                    }

//                    break;
//            }

//            return new Guid(guidBytes);
//        }
//    }
//}